#include "LZP.h"

LZP::LZP()
{
}

LZP::~LZP()
{
}

int LZP::comprimir(string nombreArch, BitHandlerOutput &pbho, int posi)
{
	BloqueTexto bt(nombreArch);
	manejadorDeArboles manejador;
	pbho.seek(posi);
	manejador.setBitHandlerOutput(pbho);
	while(!bt.finArchivo())
	{
		char ctx1,ctx2;
		int pos=2;
		ctx1=bt[0];
		ctx2=bt[1];
		manejador.emitirCaracter((unsigned int)ctx1);
		manejador.emitirCaracter((unsigned int)ctx2);

		Indice indice;
		while(!bt.finBloque())
		{
			Compresion*cmp=new Compresion(pos);
			cmp->setContexto(ctx1,ctx2);
			cmp=indice.generarCompresion(cmp,bt);
			manejador.emitirLongitud(cmp->getLongitud());
			pos+=cmp->getLongitud();
			if(bt.finArchivo())
			{
				bt.setFinBloque(true);
				manejador.emitirEof();
			}
			else
			{
				manejador.emitirCaracter(bt[pos]);
				ctx1=bt[pos-1];
				ctx2=bt[pos];
				pos++;
			}
		}
		if(!bt.finArchivo())
			bt.llenarBloque();
	}
	return 0;
}

void LZP::descomprimir(string nombreArch, BitHandlerInput &pbhi, int pos){
	BloqueTextoSalida bts(nombreArch);
	manejadorDeArboles manejador;
	manejador.setBitHandlerInput(pbhi);
	pbhi.seek(pos);

	while(!bts.finArchivo())
	{
		char ctx1,ctx2;
		int pos=2;
		ctx1=manejador.obtenerCaracter();
		bts.setCaracterEnPos(ctx1,0);
		ctx2=manejador.obtenerCaracter();
		bts.setCaracterEnPos(ctx2,1);
		Indice indice;

		while(!bts.finBloque())
		{
			int longi = manejador.obtenerLongitud();
			int carac = manejador.obtenerCaracter();
			if(pbhi.eofVirtual())
			{
				bts.setFinBloque(true);
				bts.setFinArchivo(true);
			}

			Compresion*cmp=new Compresion(pos);
			cmp->setLongitud(longi);
			cmp->setCaracter(carac);

			cmp->setContexto(ctx1,ctx2);
			cmp=indice.generarDescompresion(cmp,bts);

			pos+=longi;
			ctx1=bts[pos-1];
			ctx2=bts[pos];
			pos++;
		}
		if(!bts.finArchivo())
			bts.vaciarBloque();
	}
	bts.vaciarBloque();
}
